﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using Newtonsoft.Json;

namespace System.Map
{
    public static class BaiduApiGeocoding
    {
        private const string AccessKey = "8f02b3ab2986a4c6abfe54948022cc67";
        /// <summary>
        /// 将坐标反向转换为地址,并返回坐标bd09ll百度墨卡托坐标
        /// </summary>
        /// <param name="lat"></param>
        /// <param name="lng"></param>
        /// <param name="locationType"></param>
        /// <returns></returns>
        public static BaiduGeo<GeoResult> Geo(double lat, double lng, LocationType locationType)
        {
            const string baseUrl = "http://api.map.baidu.com/geocoder/v2/?ak={0}&callback=&location={1},{2}&output=json&pois=0&coordtype={3}";
            string coordtype;
            if (locationType == LocationType.GpsLocation)
            {
                coordtype = "wgs84ll";
            }
            else if (locationType == LocationType.BaiduLocation)
            {
                coordtype = "bd09ll";
            }
            else
            {
                coordtype = "bd09ll";
                //throw new NotSupportedException("不支持此坐标:" + locationType.ToString());
            }
            string url = string.Format(baseUrl, AccessKey, lat, lng, coordtype);
            string rawJson = string.Empty;
            BaiduGeo<GeoResult> result;
            try
            {
                try
                {
                    using (var client = new WebClient())
                    {
                        var stream = client.OpenRead(url);
                        if (stream != null)
                        {
                            using (var reader = new StreamReader(stream))
                            {
                                rawJson = reader.ReadToEnd();
                            }
                        }
                    }
                }
                catch (WebException)//偶尔会出现网络超时的情况，出现后，再试一次
                {
                    using (var client = new WebClient())
                    {
                        var stream = client.OpenRead(url);
                        if (stream != null)
                        {
                            using (var reader = new StreamReader(stream))
                            {
                                rawJson = reader.ReadToEnd();
                            }
                        }
                    }
                }
                if (!string.IsNullOrEmpty(rawJson))
                {
                    result = JsonConvert.DeserializeObject<BaiduGeo<GeoResult>>(rawJson);
                    return result;
                }
            }
            catch (Exception ex)
            {
                ex.Error("Gps坐标转Baidu坐标出错,原始的rawJson:" + rawJson);
            }
            result = new BaiduGeo<GeoResult>
                {
                    Result =
                        {
                            Location = new Location {Lat = lat, Lng = lng},
                            AddressComponent = new AddressComponent {StreetNumber = ""}
                        }
                };
            return result;
        }

        /// <summary>
        /// 将坐标反向转换为地址
        /// </summary>
        /// <param name="latlng"></param>
        /// <param name="locationType"></param>
        /// <returns></returns>
        public static BaiduGeo<GeoResult> Geo(this Location latlng, LocationType locationType)
        {
            return Geo(latlng.Lat, latlng.Lng, locationType);
        }

        /// <summary>
        /// 将地址转换为坐标
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        public static BaiduGeo<ReGeoResult> Geo(string address)
        {
            const string baseUrl = "http://api.map.baidu.com/geocoder/v2/?callback=&output=json&ak={0}&address={1}";
            string url = string.Format(baseUrl, AccessKey, HttpUtility.UrlEncode(address, Encoding.UTF8));
            try
            {
                using (var client = new WebClient())
                {
                    var stream = client.OpenRead(url);
                    if (stream != null)
                    {
                        using (var reader = new StreamReader(stream))
                        {
                            string rawJson = reader.ReadToEnd();
                            var result = JsonConvert.DeserializeObject<BaiduGeo<ReGeoResult>>(rawJson);
                            return result;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ex.Error("将地址转换为坐标出错", "MapApiGeocoding");
            } 
            return null;
        }
    }
}
